<script setup>
import request from './utils/request'
import 上传图标 from '@/assets/上传.png'
import { ref, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
const fileList = ref([])
const dragUploadRef = ref(null)

const handleEntry = (entry) => {
  if (entry.isFile) {
    entry.file((file) => {
      console.log(file)
      const fileReader = new FileReader()
      fileReader.readAsDataURL(file)
      fileReader.onload = () => {
        const base64 = fileReader.result
        fileList.value.push({
          file: file,
          filename: file.name,
          type: file.type,
          size: (file.size / 1024 / 1024).toFixed(2) + 'MB',
          status: '等待上传',
          imageUrl: base64
        })
      }
    })
    return
  }
  const reader = entry.createReader()
  reader.readEntries((entries) => {
    for (const entry of entries) {
      handleEntry(entry)
    }
  })
}
onMounted(() => {
  dragUploadRef.value.addEventListener('dragenter', (e) => {
    e.preventDefault()
  })
  dragUploadRef.value.addEventListener('dragover', (e) => {
    e.preventDefault()
  })
  dragUploadRef.value.addEventListener('drop', (e) => {
    e.preventDefault()
    const items = e.dataTransfer.items
    for (const item of items) {
      const entry = item.webkitGetAsEntry()
      handleEntry(entry)
    }
  })
})

const fileInput = ref(null)
const isChooseDirector = ref(false)

const handleFileClick = () => {
  isChooseDirector.value = false
  nextTick(() => fileInput.value.click())
}
const handleDirectorClick = () => {
  isChooseDirector.value = true
  nextTick(() => fileInput.value.click())
}
// 处理文件/文件夹选择
const handleFileChange = (e) => {
  const files = e.target.files
  for (const file of files) {
    fileList.value.push({
      file: file,
      filename: file.name,
      type: file.type,
      size: (file.size / 1024 / 1024).toFixed(2) + 'MB',
      status: '等待上传',
      imageUrl: URL.createObjectURL(file)
    })
  }
}

// 点击开始上传
const successCount = ref(0)

const upload = () => {
  fileList.value.forEach((file) => {
    if (file.status !== '等待上传') return
    uploadFun(file)
  })
}

// 点击取消上传
const cancelUpload = (file) => {
  if (file.status === '上传成功') {
    ElMessage.warning('该文件已上传完成')
    return
  }
  if (file.abortController) {
    file.abortController.abort('用户取消上传')
    file.status = '上传已取消'
  } else {
    ElMessage.warning('该文件还未开始上传')
  }
}

// 上传文件函数
const uploadFun = async (file) => {
  if (file.file.size > 1024 * 1024) {
    file.status = '文件大小超过1MB，上传失败'
    return
  }
  const formData = new FormData()
  formData.append('image', file.file)
  // 1. 创建一个 AbortController 实例
  const abortController = new AbortController()
  file.abortController = abortController
  // 2. 发起请求，并传入 signal
  const res = await request.post('/v1_0/upload', formData, {
    signal: abortController.signal,
    onUploadProgress: (progressEvent) => {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
      file.status = `上传中 ${percentCompleted}%`
      file.percentCompleted = percentCompleted
    }
  })
  file.status = '上传成功'
  successCount.value++
}

// 点击单个上传或重传
const uploadFile = (file) => {
  if (file.status === '等待上传') {
    uploadFun(file)
  } else if (file.status === '上传已取消') {
    uploadFun(file)
  } else {
    ElMessage.warning('该文件已上传完成')
  }
}
// 点击删除文件
const deleteFile = (file) => {
  fileList.value = fileList.value.filter((item) => item !== file)
  successCount.value--
}
</script>

<template>
  <div class="container">
    <div class="upload" ref="dragUploadRef">
      <div class="upload-desc">
        <img class="upload-icon" :src="上传图标" alt="" />
        将目录或多个文件拖拽到此进行扫描
      </div>
      <div class="upload-desc">支持的文件类型： .jpg、.jpeg、.png</div>
      <div class="upload-desc">每个文件允许的最大尺寸： 1M</div>
    </div>
    <div class="btn-box">
      <input
        type="file"
        multiple
        v-show="false"
        :webkitdirectory="isChooseDirector"
        :mozdirectory="isChooseDirector"
        :odirectory="isChooseDirector"
        ref="fileInput"
        @change="handleFileChange"
      />
      <button @click="handleFileClick">选择文件</button>
      <button @click="handleDirectorClick">选择文件夹</button>
    </div>
    <div class="upload-table">
      <el-table style="width: 100%" :data="fileList">
        <el-table-column prop="filename" label="文件名"> </el-table-column>
        <el-table-column width="180" label="预览">
          <template #default="scope">
            <el-image
              :src="scope.row.imageUrl"
              preview-teleported
              :preview-src-list="[scope.row.imageUrl]"
            />
          </template>
        </el-table-column>
        <el-table-column prop="type" label="类型"> </el-table-column>
        <el-table-column prop="size" label="大小"> </el-table-column>
        <el-table-column prop="status" label="状态" width="180">
          <template #default="{ row }">
            <el-tag size="large" type="info" v-if="row.status === '等待上传'">{{
              row.status
            }}</el-tag>
            <el-tag size="large" type="success" v-else-if="row.status === '上传成功'">{{
              row.status
            }}</el-tag>
            <el-tag size="large" type="danger" v-else-if="row.status === '上传已取消'">{{
              row.status
            }}</el-tag>
            <div v-else>
              {{ row.status }}
              <el-progress
                :text-inside="false"
                :stroke-width="6"
                status="success"
                :percentage="row.percentCompleted"
              />
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="250">
          <template #default="scope">
            <el-button type="primary" size="small" @click="uploadFile(scope.row)">上传</el-button>
            <el-button type="warning" size="small" @click="cancelUpload(scope.row)">取消</el-button>
            <el-button type="danger" size="small" @click="deleteFile(scope.row)">删除</el-button>
          </template>
        </el-table-column>
        <template #empty>
          <el-empty></el-empty>
        </template>
      </el-table>
    </div>
    <div class="upload-tag">
      <el-tag type="info">文件数量：{{ fileList.length }}</el-tag>
      <el-tag type="success">成功上传：{{ successCount }}</el-tag>
      <el-tag type="info"
        >总大小：{{ fileList.reduce((acc, cur) => acc + cur.file.size, 0) }}byte</el-tag
      >
    </div>
    <div style="margin-top: 20px">
      <el-button type="primary" @click="upload">开始上传</el-button>
    </div>
  </div>
</template>

<style scoped lang="scss">
.container {
  width: 80%;
  margin: 0 auto;
  height: 100vh;
  .upload {
    height: 200px;
    margin: 10px auto;
    border: 1px dashed #999;
    &:hover {
      border-color: rgb(108, 194, 228);
    }
    .upload-desc {
      margin: 20px 0;
      text-align: center;
      color: #999;
      .upload-icon {
        width: 50px;
        height: 50px;
        vertical-align: middle;
      }
    }
  }
  .btn-box {
    margin-top: 20px;
    button {
      padding: 8px 10px;
      background-color: #1353d1;
      color: #fff;
      margin-right: 10px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
  }
  .upload-tag {
    margin-top: 20px;
    display: flex;
    gap: 20px;
  }
}
</style>
